﻿using System;
using System.Diagnostics;

namespace SfsTools.Core
{
    /// <summary>
    /// Validates paths so they dont contain any of the reserved characters.
    /// </summary>
    internal class PathValidator
    {
        #region Properties

        /// <summary>
        /// Contains an array of the forbidden characters in paths and names.
        /// </summary>
        private static readonly Char[] FForbiddenCharsInPathName;

        #endregion

        #region Methods

        /// <summary>
        /// Ensures that the specified name is a legal directory name.
        /// </summary>
        /// <param name="name">The name of the subdirectory.</param>
        /// <exception cref="ArgumentNullException">The argument <paramref name="name"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">The argument <paramref name="name"/> contains invalid characters.</exception>
        [DebuggerStepThrough]
        public static void ValidateDirectoryName(String name)
        {
            if (name == null)
                throw new ArgumentNullException("name");
            if (name == String.Empty || name == new String('.', 1) || name == new String('.', 2))
                throw new ArgumentException();
            // Disallow these in new names.
            // " (double quote, 0x0022)
            // * (asterix, 0x002A)
            // : (colon, 0x003A)
            // < (less than sign, 0x003C)
            // > (greater than sign, 0x003E)
            // ? (question mark, 0x003F)
            // \ (backward slash, 0x005C)
            // DEL (delete, 0x007F)
            // NBSP (no break space character, 0x00A0)
            if (name.IndexOfAny(FForbiddenCharsInPathName) > -1)
                throw new InvalidCharacterInDirectoryNameException("name");
        }

        /// <summary>
        /// Ensures that the specified name is a legal file name.
        /// </summary>
        /// <param name="name">The name of the file.</param>
        /// <exception cref="ArgumentNullException">The argument <paramref name="name"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">The argument <paramref name="name"/> contains invalid characters.</exception>
        [DebuggerStepThrough]
        public static void ValidateFileName(String name)
        {
            if (name == null)
                throw new ArgumentNullException("name");
            if (name == String.Empty)
                throw new ArgumentException();
            // Disallow these in new names.
            // " (double quote, 0x0022)
            // * (asterix, 0x002A)
            // : (colon, 0x003A)
            // < (less than sign, 0x003C)
            // > (greater than sign, 0x003E)
            // ? (question mark, 0x003F)
            // \ (backward slash, 0x005C)
            // DEL (delete, 0x007F)
            // NBSP (no break space character, 0x00A0)
            if (name.IndexOfAny(FForbiddenCharsInPathName) > -1)
                throw new InvalidCharacterInFileNameException("name");
        }

        #endregion

        #region Constructors
        /// <overloads>Initializes a new instance of <see cref="PathValidator"/>.</overloads>
        /// <summary>
        /// Initializes a new instance of <see cref="PathValidator"/>.
        /// </summary>
        [DebuggerStepThrough]
        public PathValidator()
            : base()
        {
        }
        /// <summary>
        /// Initializes <see cref="PathValidator"/>.
        /// </summary>
        [DebuggerStepThrough]
        static PathValidator()
        {
            FForbiddenCharsInPathName = new Char[10 + 32];
            int i = 0;
            for (; i <= 31; i++)
                FForbiddenCharsInPathName[i] = (Char)i;
            FForbiddenCharsInPathName[i++] = '\"';
            FForbiddenCharsInPathName[i++] = '*';
            FForbiddenCharsInPathName[i++] = ':';
            FForbiddenCharsInPathName[i++] = '<';
            FForbiddenCharsInPathName[i++] = '>';
            FForbiddenCharsInPathName[i++] = '?';
            FForbiddenCharsInPathName[i++] = '\\';
            FForbiddenCharsInPathName[i++] = '/';
            FForbiddenCharsInPathName[i++] = '\u007F';
            FForbiddenCharsInPathName[i++] = '\u00A0';
        }
        #endregion
    }
}
